package com.loren.demo30.initializer;

import com.loren.demo30.utils.JdbcUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.lang.NonNull;

import java.sql.Connection;
import java.sql.Statement;

@Slf4j
public class CustomApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(@NonNull ConfigurableApplicationContext applicationContext) {
        log.info("======= CustomApplicationContextInitializer initialize Start =======");
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        String driverClassName = environment.getProperty("spring.datasource.driver-class-name");
        String datasourceUrl = environment.getProperty("spring.datasource.url");
        String username = environment.getProperty("spring.datasource.username");
        String password = environment.getProperty("spring.datasource.password");
        this.createDatabaseIfDoesNotExist(driverClassName, datasourceUrl, username, password);
        log.info("======= CustomApplicationContextInitializer initialize Finish =======");
    }

    private void createDatabaseIfDoesNotExist(String driverClassName, String datasourceUrl, String username, String password) {
        Connection connection = null;
        Statement statement = null;
        try {
            DatasourceSplitInfo splitInfo = this.getDatabaseUrlWithoutDatabaseName(datasourceUrl);
            connection = JdbcUtils.getConnection(driverClassName, splitInfo.getUrlWithoutName(), username, password);
            statement = connection.createStatement();
            statement.executeUpdate("create database if not exists " + splitInfo.getName() + " default character set utf8mb4 COLLATE utf8mb4_general_ci");
        } catch (Exception e) {
            log.error("create database error", e);
        } finally {
            JdbcUtils.release(null, statement, connection);
        }
    }

    private DatasourceSplitInfo getDatabaseUrlWithoutDatabaseName(String datasourceUrl) {
        String baseUrl = datasourceUrl.substring(0, datasourceUrl.indexOf("?"));
        String databaseName = baseUrl.substring(baseUrl.lastIndexOf("/"));
        DatasourceSplitInfo splitInfo = new DatasourceSplitInfo();
        splitInfo.setName(databaseName.substring(1));
        splitInfo.setUrlWithoutName(datasourceUrl.replace(databaseName, ""));
        return splitInfo;
    }

    @Getter
    @Setter
    private static class DatasourceSplitInfo {
        private String name;

        private String urlWithoutName;
    }

}
